package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.CartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.vo.SkuPriceVo;
import com.spzx.product.api.service.RemoteProductSkuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RemoteProductSkuService remoteProductSkuService;

    private String getCartKey() {
        //获取用户id
        Long userId = SecurityUtils.getUserId();
        //定义key user:userId:cart
        return "user:cart:" + userId;
    }

    /**
     * 添加购物车
     * @param skuId
     * @param skuNum
     */
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //获取在redis中保存的购车的Key
        String cartKey = getCartKey();
        //获取购物车中该购物项
        CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(cartKey, skuId.toString());
        //判断是否为null
        if (cartInfo != null) {
            Integer totalCount = cartInfo.getSkuNum() + skuNum;
            //证明原来购物车已经存在该购物项,只需要获取原来的数量,再加上传过来的数量
            cartInfo.setSkuNum(totalCount > 99 ? 99 : totalCount);
        } else {
            //远程调用商品微服务,根据skuId获取商品sku信息
            R<ProductSku> productById = remoteProductSkuService.getProductSkuById(skuId, SecurityConstants.INNER);
            if (R.FAIL == productById.getCode()) {
                //调用失败
                throw new ServiceException("远程调用失败");
            }
            //获取商品sku信息
            ProductSku productSku = productById.getData();
            //证明原来购物车中没有该购物项,属于第一次添加
            cartInfo = new CartInfo();
            //第一次添加
            cartInfo.setSkuNum(1);
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuName(productSku.getSkuName());
            //设置商品价格
            cartInfo.setCartPrice(productSku.getSalePrice());
            //设置商品实时价格
            cartInfo.setSkuPrice(productSku.getSalePrice());
            //设置商品的图片
            cartInfo.setThumbImg(productSku.getThumbImg());
        }
        //将商品放到购物车中
        redisTemplate.opsForHash().put(cartKey, skuId.toString(), cartInfo);
    }

    /**
     * 查询购物车列表
     * @return
     */
    @Override
    public List<CartInfo> cartList() {
        //获取购物车的key
        String cartKey = getCartKey();
        //获取购物车
        List<CartInfo> cartList = redisTemplate.opsForHash().values(cartKey);
        //遍历
        cartList.forEach(cartInfo -> {
            R<SkuPriceVo> skuPriceVoBySkuId = remoteProductSkuService.getSkuPriceVoBySkuId(cartInfo.getSkuId(), SecurityConstants.INNER);
            if (R.FAIL == (skuPriceVoBySkuId.getCode())) {
                //远程调用失败
                throw new ServiceException("远程调用商品微服务根据skuId查询SkuPrice失败");
            }
            //获取SkuPrice
            SkuPriceVo skuPriceVo = skuPriceVoBySkuId.getData();
            //设置实时价格
            cartInfo.setSkuPrice(skuPriceVo.getSalePrice());
            //将修改之后的购物项重新放进redis一遍
            redisTemplate.opsForHash().put(cartKey, skuPriceVo.getSkuId().toString(), cartInfo);
        });
        return cartList;
    }

    @Override
    public void deleteCartInfo(Long skuId) {
        //获取购物车的key
        String cartKey = getCartKey();
        Boolean flag = redisTemplate.opsForHash().hasKey(cartKey, skuId.toString());
        if (flag) {
            //根据skuId删除购物车中的购物项
            redisTemplate.opsForHash().delete(cartKey, skuId.toString());
        }

    }

    @Override
    public void clearCartInfo() {
        //获取购物车的key
        String cartKey = getCartKey();
        //清空购物车
        redisTemplate.delete(cartKey);
    }

    @Override
    public void updateCartInfo(Long skuId, Integer status) {
        //获取key
        String cartKey = getCartKey();
        //判断是否有购物项
        Boolean flag = redisTemplate.opsForHash().hasKey(cartKey, skuId.toString());
        if (flag) {
            //获取该购物项
            CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(cartKey, skuId.toString());
            //设置选中状态
            cartInfo.setIsChecked(status);
            //重新放进去
            redisTemplate.opsForHash().put(cartKey, skuId.toString(), cartInfo);
        }

    }

    @Override
    public void allCheckCart(Integer status) {
        //获取key
        String cartKey = getCartKey();
        //获取所有的购物项
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(cartKey);
        //验空
        if(!CollectionUtils.isEmpty(cartInfoList)){
            cartInfoList.forEach(cartInfo -> {
                cartInfo.setIsChecked(status);
                //重新放进redis
                redisTemplate.opsForHash().put(cartKey,String.valueOf(cartInfo.getSkuId()),cartInfo);
            });
        }
    }

    /**
     * 清除已选中的购物项
     * @param userId
     */
    @Override
    public void clearCheckedCartInfo(Long userId) {
        //设置向redis中获取购物车的key
        String cartKey = "user:cart:" +userId;
        //获取购物车所有的购物项目
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(cartKey);
        //获取已经选中的购物项目
        List<CartInfo> checkCartInfoList = cartInfoList.stream().filter(cartInfo ->
                cartInfo.getIsChecked() == 1
        ).toList();
        //遍历
        checkCartInfoList.forEach(cartInfo -> {
            //删除购物项
            redisTemplate.opsForHash().delete(cartKey,String.valueOf(cartInfo.getSkuId()));
        });
    }

    /**
     * 获取已经选中的购物项
     * @param userId
     * @return
     */
    @Override
    public List<CartInfo> getCheckedCartInfo(Long userId) {
        //设置向redis中获取购物车的key
        String cartKey = "user:cart:" +userId;
        //获取购物车所有的购物项目
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(cartKey);
        //获取已经选中的购物项目
        List<CartInfo> checkCartInfoList = cartInfoList.stream().filter(cartInfo ->
                cartInfo.getIsChecked() == 1
        ).toList();
        return checkCartInfoList;
    }
}
